<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */

namespace app\service\report;

use app\enum\ReportRecordEnum;
use app\model\report\ReportRecordExcelModel;
use app\model\report\ReportRecordExcelTemplatesModel;
use app\model\report\ReportRecordListModel;
use app\model\ReportRecordModel;
use app\model\StaffFsAccessTokenModel;
use app\model\StaffModel;
use app\service\BaseService;
use app\service\notice\NoticeInterface;
use app\service\notice\NoticeService;
use app\service\report\kuaishou\ProcessingDataService as KSData;
use app\service\report\ocean\ProcessingDataService as OeData;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\Model;

class ReportRecordListService extends BaseService
{
    /**
     * 获取发送日报表数据.
     *
     * @param ReportRecordExcelModel $obj 报表对象
     * @param int $sendDate 发送时间
     */
    public static function addData(ReportRecordExcelModel $obj, int $sendDate = 0): bool
    {
        if (! $obj->getKey()) {
            return self::setError('报表数据ID失败');
        }
        if ($obj->getAttr('is_send') == ReportRecordExcelModel::SEND_NO) {
            return self::setError('报表数据已关闭');
        }
        $sendTime = json_decode($obj->getAttr('send_time'), true);
        if (! $sendTime) {
            return true;
        }
        try {
            Db::startTrans();
            foreach ($sendTime as $val) {
                $sendHour = intval($val);
                $model = self::getReportRecordListModel($obj->getKey(), $sendDate, $sendHour);
                if (! $model instanceof ReportRecordListModel) {
                    throw new \Exception('获取发送时报记录模型失败');
                }
                $model->setAttrs([
                    'report_record_id' => $obj->getKey(),
                    'receive_staff_ids' => $obj->getAttr('receive_staff_ids'),
                    'date' => $sendDate,
                    'hour' => $sendHour,
                    'set_date' => time(),
                ]);
                $model->save();
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return self::setError($e->getMessage());
        }
        return true;
    }

    /**
     * 获取当天需要发送的日报数据.
     *
     * @param int $reportRecordId 报表id
     * @param int $sendDate 发送日期
     * @param int $sendHour 发送时段
     * @return null|array|mixed|Model|ReportRecordListModel
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getReportRecordListModel(int $reportRecordId = 0, int $sendDate = 0, int $sendHour = 0)
    {
        $where = [
            'report_record_id' => $reportRecordId,
            'date' => $sendDate,
            'hour' => $sendHour,
        ];
        $model = (new ReportRecordListModel())->where($where)->field(true)->find();
        if (! $model instanceof ReportRecordListModel) {
            $model = new ReportRecordListModel();
        }
        return $model;
    }

    /**
     * 获取待发送报表ids.
     *
     * @param int $sendTime 发送时间
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getListIds(int $sendTime = 0, int $sendDate = 0)
    {
        return (new ReportRecordListModel())
            ->where('hour', $sendTime)
            ->where('date', $sendDate)
            ->where('status', ReportRecordListModel::STATUS_NO) // 0：待发送
            ->select();
    }

    /**
     * 更新状态
     *
     * @param int $listId 发送记录ID
     * @param int $status 状态值
     */
    public static function setStatus(int $listId = 0, int $status = 0): ReportRecordListModel
    {
        return (new ReportRecordListModel())->update(['status' => $status, 'update_time' => time()], ['id' => $listId]);
    }

    /**
     * 获取包周报内容添加到内容表.
     *
     * @param int $listId 发送记录ID
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getReportRecordContent(int $listId = 0): bool
    {
        $listModel = (new ReportRecordListModel())->find($listId);
        if (! $listModel instanceof ReportRecordListModel || ! $listModel->getKey()) {
            return self::setError('实时报表数据查询失败');
        }
        return (new ReportRecordFetchService($listModel))->getData();
    }

    /**
     * 获取已同步数据报表.
     *
     * @return array|Collection|ReportRecordModel[]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getListStatus()
    {
        return (new ReportRecordListModel())
            ->where('status', ReportRecordListModel::STATUS_SYNC)
            ->select();
    }

    /**
     * 获取需要发送的日报数据.
     * @param int $reportRecordId 报表主表id
     * @return bool|void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getPushReportRecordSend(int $reportRecordId = 0)
    {
        $model = (new ReportRecordListModel())->find($reportRecordId);
        if (! $model instanceof ReportRecordListModel || ! $model->getKey()) {
            return self::setError('报表数据查收失败');
        }
        try {
            $item = (new ReportRecordExcelModel())->where('is_send', ReportRecordExcelModel::SEND_YES)->find($model['report_record_id']);
            if (! empty($item)) {
                if (empty($model->getAttr('file_url'))) {
                    $item = $item->toArray();
                    $item['sendDate'] = $model->getAttr('date');
                    $item['sendTime'] = $model->getAttr('hour');
                    $item['templates'] = ReportRecordExcelTemplatesModel::where('report_record_id', $model['report_record_id'])->find()->toArray();
                    // 处理数据
                    if ($item['media_id'] == ReportRecordEnum::OE_MEDIA) { // 巨量
                        $data = OeData::processingData($item);
                    } elseif ($item['media_id'] == ReportRecordEnum::KS_MEDIA) { // 快手
                        $data = KSData::processingData($item);
                    }
                    $data = ! empty($data) ? $data : [];
                    $merge = ! empty(json_decode($item['templates']['data'], true)[0]['config']['merge']) ? json_decode($item['templates']['data'], true)[0]['config']['merge'] : [];
                    // 生成excel文件
                    $fileUrl = ReportFileService::getFile($data, $merge, $item);
                    unset($data);
                } else {
                    $fileUrl = $model->getAttr('file_url');
                }
                if ($fileUrl) {
                    $model->setAttr('file_url', $fileUrl);
                    $model->setAttr('status', ReportRecordListModel::STATUS_WAIT_SEND);
                    if (! $model->save()) {
                        return self::setError('添加发送文件存储失败');
                    }
                    return true;
                }
            } else {
                $model->setAttr('status', ReportRecordListModel::STATUS_FAIL);
                $model->setAttr('error_msg', '暂无数据');
                $model->save();
                return self::setError('暂无数据');
            }
        } catch (\Exception $e) {
            $model->setAttr('status', ReportRecordListModel::STATUS_FAIL);
            $model->setAttr('error_msg', $e->getMessage());
            $model->save();
            return self::setError($e->getMessage());
        }
    }

    /**
     * 获取实时发送报表列表数据.
     * @return array|Collection|ReportRecordModel[]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getListSendIds(int $sendDate = 0)
    {
        return (new ReportRecordListModel())
            ->where('status', ReportRecordListModel::STATUS_WAIT_SEND) // 3：待发送
            ->where('date', $sendDate)
            ->select();
    }

    /**
     * 获取需要发送的日报数据.
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getListReportSend(ReportRecordListModel $reportListModel): bool
    {
        $reportRecordId = $reportListModel->getAttr('report_record_id');
        $item = (new ReportRecordExcelModel())->where('is_send', ReportRecordExcelModel::SEND_YES)->find($reportRecordId);
        if (! $item instanceof ReportRecordExcelModel || ! $item->getKey()) {
            $reportListModel->setAttr('status', ReportRecordListModel::STATUS_FAIL);
            $reportListModel->setAttr('error_msg', '暂无数据');
            $reportListModel->save();
            return self::setError(date('Y-m-d H:i:s') . 'id为' . $reportRecordId . '暂无数据');
        }
        $fileUrl = $reportListModel->getAttr('file_url');
        if (! $fileUrl) {
            return self::setError(date('Y-m-d H:i:s') . 'id为' . $reportRecordId . '的报表生成excel失败');
        }
        $reportSend = new ReportRecordSendService($item, $reportListModel);
        $res = $reportSend->reportSend();
        if (! $res) {
            return self::setError('报表发送失败');
        }
        return true;
    }
}
